﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Win32Proxy.Enums;
using Win32Proxy.Structs;

namespace Win32Proxy.Api
{
    public class User32
    {
        /// <summary>
        /// 该函数返回指定窗口客户区域或屏幕的设备上下文（DC）
        /// </summary>
        /// <param name="hwnd"></param>
        /// <returns></returns>
        [DllImport("user32.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
        public static extern IntPtr GetDC(IntPtr hwnd);

        /// <summary>
        /// 该函数释放由GetDC函数获得的指定设备上下文（DC）
        /// </summary>
        /// <param name="hwnd"></param>
        /// <param name="hDC"></param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        public static extern int ReleaseDC(IntPtr hwnd, IntPtr hDC);

        [DllImport("user32.dll")]
        public static extern bool PostMessage(int hhwnd, uint msg, IntPtr wparam, IntPtr lparam);







        /// <summary>
        /// 获取桌面窗体
        /// </summary>
        /// <returns></returns>
        [DllImport("user32.dll")]
        public static extern IntPtr GetDesktopWindow();

        #region 窗体相关

        /// <summary>
        /// 获取进程ID
        /// </summary>
        /// <param name="hWnd"></param>
        /// <param name="lpdwProcessId"></param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        static extern uint GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId);

        /// <summary>
        /// 获取窗体的DC
        /// </summary>
        /// <param name="ptr"></param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        public static extern IntPtr GetWindowDC(IntPtr ptr);

        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetWindowInfo(IntPtr hwnd, ref WINDOWINFO pwi);

        [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hwndAfter, int x, int y, int width, int height, int flags);

        [DllImport("user32.dll", EntryPoint = "ShowWindow")]
        public static extern bool ShowWindow(System.IntPtr hWnd, int nCmdShow);

        [DllImport("User32.dll")]
        public static extern bool ShowWindowAsync(System.IntPtr hWnd, int cmdShow);

        /// <summary>
        /// 根据名称查找窗体
        /// </summary>
        /// <param name="lpClassName"></param>
        /// <param name="lpWindowName"></param>
        /// <returns></returns>
        [DllImport("User32.dll", EntryPoint = "FindWindow")]
        public static extern IntPtr FindWindow(string? lpClassName, string? lpWindowName);

        [DllImport("user32.dll", EntryPoint = "FindWindowEx")]
        public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

        /// <summary>
        /// 获取窗口的屏幕坐标的位置和大小
        /// </summary>
        /// <param name="hwnd"></param>
        /// <param name="lpRect"></param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        public static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);

        [DllImport("user32.dll")]
        public static extern bool GetClientRect(IntPtr hwnd, out RECT lpRect);

        [DllImport("user32.dll", EntryPoint = "ClientToScreen")]
        public static extern bool ClientToScreen(IntPtr hwnd, out Point lpPoint);

        [DllImport("user32.dll", EntryPoint = "ScreenToClient")]
        public static extern bool ScreenToClient(IntPtr hwnd, out Point lpPoint);


        [DllImport("user32.dll")]
        public static extern bool PrintWindow(IntPtr hwnd, IntPtr hdcBlt, uint nFlags);

        /// <summary> 
        /// 回调函数代理 
        /// </summary> 
        public delegate bool CallBack(IntPtr hwnd, int lParam);

        /// <summary> 
        /// 回调函数代理 
        /// </summary> 
        public delegate bool WndEnumProc(IntPtr hwnd, uint lParam);

        [DllImport("user32.dll")]
        public static extern int EnumWindows(CallBack lpfn, int lParam);

        [DllImport("user32.dll")]
        public static extern bool EnumWindows(WndEnumProc lpfn, uint lParam);

        [DllImport("user32.dll")]
        public static extern int EnumChildWindows(IntPtr hWndParent, CallBack lpfn, int lParam);

        [DllImport("User32.dll", EntryPoint = "GetParent")]
        public static extern IntPtr GetParent(IntPtr hWnd);

        [DllImport("user32.dll", CharSet = CharSet.Unicode)]
        public static extern bool GetWindowText(IntPtr hWnd, StringBuilder text, int nMaxCount);

        [DllImport("user32.dll")]
        public static extern int GetWindowTextLength(IntPtr hWnd);

        [DllImport("user32.dll", CharSet = CharSet.Unicode)]
        public static extern bool GetClassName(IntPtr hWnd, StringBuilder text, int nMaxCount);

        [DllImport("User32.dll")]
        public static extern bool SetForegroundWindow(System.IntPtr hWnd);

        /// <summary>
        /// Retrieve the foreground window
        /// </summary>
        /// <returns>Handle of the foreground window</returns>
        [DllImport("user32.dll")]
        public static extern IntPtr GetForegroundWindow();

        /// <summary>
        /// Check whether a window handle is valid
        /// </summary>
        /// <param name="hwnd">The handle to be examed</param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        public extern static bool IsWindow(IntPtr hwnd);

        /// <summary>
        /// Check whether a window is visible
        /// </summary>
        /// <param name="hwnd">Handle of the window</param>
        /// <returns>Return true if the window is visible, false otherwise</returns>
        [DllImport("user32.dll")]
        public static extern bool IsWindowVisible(IntPtr hwnd);

        /// <summary>
        /// 检查窗体是否最小化
        /// </summary>
        /// <param name="hWnd"></param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        public static extern bool IsIconic(IntPtr hWnd);

        [DllImport("user32.dll")]
        public static extern bool IsZoomed(IntPtr hWnd);

        /// <summary>
        /// Check whether a window is miminized
        /// </summary>
        /// <param name="hwnd">Handle of the window</param>
        /// <returns>Return true if the specified window is minimized, false otherwise</returns>
        [DllImport("user32.dll", EntryPoint = "IsIconic")]
        public static extern bool IsMinimized(IntPtr hwnd);

        /// <summary>
        /// Check whether a window is maximized
        /// </summary>
        /// <param name="hwnd">Handle of the window</param>
        /// <returns>Return true if the specified window is maxmized, false otherwise</returns>
        [DllImport("user32.dll", EntryPoint = "IsZoomed")]
        public static extern bool IsMaximized(IntPtr hwnd);

        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr SetFocus(IntPtr hWnd);
        #endregion




        #region 获取显示器信息 
        /// <summary>
        /// 枚举显示器
        /// </summary>
        /// <param name="lpDevice"></param>
        /// <param name="iDevNum"></param>
        /// <param name="lpDisplayDevice"></param>
        /// <param name="dwFlags"></param>
        /// <returns></returns>
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern bool EnumDisplayDevices(string? lpDevice, uint iDevNum, ref DISPLAY_DEVICE lpDisplayDevice, uint dwFlags);

        /// <summary>
        /// 更具窗体句柄获取窗体所在的显示器
        /// </summary>
        /// <param name="hwnd"></param>
        /// <param name="dwFlags">
        /// MONITOR_DEFAULTTONEAREST 0 返回最靠近窗口的显示监视器的句柄
        /// MONITOR_DEFAULTTONULL 1 返回 NULL。
        /// MONITOR_DEFAULTTOPRIMARY 2 返回主显示监视器的句柄。
        /// </param>
        /// <returns></returns>
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern nint MonitorFromWindow(nint hwnd, uint dwFlags);

        /// <summary>
        /// 获取显示器信息
        /// </summary>
        /// <param name="hMonitor"></param>
        /// <param name="lpmi"></param>
        /// <returns></returns>
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern bool GetMonitorInfo(nint hMonitor, ref MonitorInfo lpmi);

        /// <summary>
        /// 读取当前显示设置，并枚举所有受支持的显示设置。
        /// </summary>
        /// <param name="lpszDeviceName"></param>
        /// <param name="iModeNum"></param>
        /// <param name="lpDevMode"></param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        public static extern int EnumDisplaySettings(string lpszDeviceName, int iModeNum, ref DEVMODE lpDevMode);

        [DllImport("user32.dll")]
        public static extern int ChangeDisplaySettings(ref DEVMODE devMode, int flags);
        #endregion

        /// <summary>
        /// 用于检索有关系统信息的各种度量标准。该函数通常用于获取有关屏幕、显示器和系统设置的信息
        /// </summary>
        /// <param name="nIndex"></param>
        /// <returns></returns>
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int GetSystemMetrics(int nIndex);

        /// <summary>
        /// 用于设置窗口 DPI 感知上下文的函数。这个函数用于告诉操作系统如何处理窗口的 DPI（Dots Per Inch，每英寸像素数）设置。在高分辨率显示器上，调整 DPI 设置可以确保应用程序在各种屏幕分辨率下都能正确显示。
        /// </summary>
        /// <param name="hwnd"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        public static extern bool SetWindowDpiAwarenessContext(IntPtr hwnd, DpiAwarenessContext context);

        /// <summary>
        /// 通常与 Windows Presentation Foundation (WPF) 或其他 GUI 框架一起使用，以确保应用程序的界面在不同 DPI 设置下保持良好的可见性和布局。
        /// </summary>
        /// <param name="hwnd"></param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        public static extern DpiAwarenessContext GetWindowDpiAwarenessContext(IntPtr hwnd);
    }
}
